package com.lyw.i01producerAndConsumer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lyw
 * @Date 2023/7/9-上午11:39
 */
class ShareLock {
  private int number = 0;
  private final ReentrantLock lock =  new ReentrantLock();
  private final Condition condition = lock.newCondition();

  public void incr() {
    lock.lock();
    try {
      while (number != 0) {
        condition.await();
      }
      System.out.println(Thread.currentThread().getName() + " :: " + ++number);
      condition.signalAll();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }

  public void decr() {
    lock.lock();
    try {
      // while 防止虚假唤醒
      // 如果不等于 1 的话应该继续等待
      while (number != 1) {
        condition.await();
      }
      System.out.println(Thread.currentThread().getName() + " :: " + --number);
      condition.signalAll();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
}
public class LockDemo {

  public static void main(String[] args) {
    final ShareLock shareLock = new ShareLock();
    new Thread(() -> {
      for (int i = 0; i < 30; i++) {
        shareLock.incr();
      }
    }, "AA").start();

    new Thread(() -> {
      for (int i = 0; i < 30; i++) {
        shareLock.decr();
      }
    }, "BB").start();

    new Thread(() -> {
      for (int i = 0; i < 30; i++) {
        shareLock.incr();
      }
    }, "CC").start();

    new Thread(() -> {
      for (int i = 0; i < 30; i++) {
        shareLock.decr();
      }
    }, "DD").start();
  }
}
